#pragma once

#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <wchar.h>
#include <windows.h>
#include <string>
#include "DesktopCapturer.h"
#define alloca _alloca
#define STACK_ARRAY(TYPE, LEN) \
  static_cast<TYPE*>(::alloca((LEN) * sizeof(TYPE)))

class Utils
{
public:
	static const int64_t kNumMillisecsPerSec = INT64_C(1000);
	static const int64_t kNumMicrosecsPerSec = INT64_C(1000000);
	static const int64_t kNumNanosecsPerSec = INT64_C(1000000000);

	static const int64_t kNumMicrosecsPerMillisec =
		kNumMicrosecsPerSec / kNumMillisecsPerSec;
	static const int64_t kNumNanosecsPerMillisec =
		kNumNanosecsPerSec / kNumMillisecsPerSec;
	static const int64_t kNumNanosecsPerMicrosec =
		kNumNanosecsPerSec / kNumMicrosecsPerSec;

	static int64_t TimeNanos();

	static bool GetScreenList(DesktopCapturer::SourceList* screens,
		std::vector<std::string>* device_names = nullptr);

	static inline std::string ToUtf8(const wchar_t* wide, size_t len) {
		int len8 = ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast<int>(len),
			nullptr, 0, nullptr, nullptr);
		char* ns = STACK_ARRAY(char, len8);
		::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast<int>(len), ns, len8,
			nullptr, nullptr);
		return std::string(ns, len8);
	}
	
	static inline std::string ToUtf8(const wchar_t* wide) {
		return ToUtf8(wide, wcslen(wide));
	}

	static bool IsScreenValid(DesktopCapturer::SourceId screen, std::wstring* device_key);

	static DesktopRect GetFullscreenRect();

	static DesktopRect GetScreenRect(DesktopCapturer::SourceId screen,
		const std::wstring& device_key);
};

